package com.qsw.paper.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qsw.paper.constant.MessageConstants;
import com.qsw.paper.constant.StatusConstants;
import com.qsw.paper.exception.ObjectException;
import com.qsw.paper.mapper.ThesesMapper;
import com.qsw.paper.mapper.ThesisReviewsMapper;
import com.qsw.paper.mapper.ThesisVersionsMapper;
import com.qsw.paper.pojo.dto.AdvisorUpdateTheseDto;
import com.qsw.paper.pojo.dto.TheseDto;
import com.qsw.paper.pojo.entity.Theses;
import com.qsw.paper.pojo.entity.ThesisReviews;
import com.qsw.paper.pojo.entity.ThesisVersions;
import com.qsw.paper.pojo.vo.ThesesVO;
import com.qsw.paper.service.IThesesService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author qsw
 * @since 2024-11-15
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ThesesServiceImpl extends ServiceImpl<ThesesMapper, Theses> implements IThesesService {

    private final ThesisReviewsMapper reviewsMapper;
    private final ThesisVersionsMapper versionsMapper;

    /**
     * 通过论文id 获取论文信息
     *
     * @param id 论文id
     * @return 论文实体
     */
    @Override
    public ThesesVO getTheseByTheseId(Integer id) {
        Theses theses = getOne(new LambdaQueryWrapper<Theses>().eq(Theses::getThesisId, id));
        if (theses == null) {
            return null;
        }
        ThesesVO thesesVO = new ThesesVO();
        BeanUtil.copyProperties(theses, thesesVO);
        ThesisReviews thesisReviews = reviewsMapper.selectOne(new LambdaQueryWrapper<ThesisReviews>()
                .eq(ThesisReviews::getThesisId, id));
        thesesVO.setReview(thesisReviews == null ? new ThesisReviews() : thesisReviews);
        thesesVO.setVersion(versionsMapper.selectOne(new LambdaQueryWrapper<ThesisVersions>()
                .eq(ThesisVersions::getThesisId, id)));
        return thesesVO;
    }

    /**
     * 添加论文
     *
     * @param theseDto dto
     */
    @Transactional
    @Override
    public void save(@NotNull TheseDto theseDto) {
        if (theseDto.getStudentId() == null || theseDto.getFileUrl() == null) {
            throw new ObjectException("学生ID和文件URL不能为空");
        }

        Integer studentId = theseDto.getStudentId();

        // 查询该学生的所有论文记录
        List<Theses> thesesList = baseMapper.selectList(new LambdaQueryWrapper<Theses>().eq(Theses::getStudentId, studentId));

        if (CollectionUtils.isEmpty(thesesList)) {
            // 学生没有任何论文记录，添加初稿
            log.info("添加初稿论文，学生ID：{}", studentId);

            // 插入论文记录
            Theses theses = Theses.builder().studentId(studentId)
                    .advisorId(theseDto.getAdvisorId()).title(theseDto.getTitle()).status(StatusConstants.ZERO) // 状态：待审核
                    .submissionDate(LocalDateTime.now()).lastUpdated(LocalDateTime.now()).build();
            baseMapper.insert(theses);

            // 插入版本信息
            ThesisVersions thesisVersions = ThesisVersions.builder().thesisId(theses.getThesisId()).versionNumber(1) // 初稿
                    .versionDate(LocalDateTime.now()).fileUrl(theseDto.getFileUrl()).status(StatusConstants.ZERO) // 状态：待审核
                    .build();
            versionsMapper.insert(thesisVersions);

            log.info("初稿论文添加成功，论文ID：{}", theses.getThesisId());
        } else {
            // 有论文记录，检查初稿和终稿状态
            Integer thesisId = thesesList.get(0).getThesisId(); // 获取最新论文ID

            // 查询版本信息
            List<ThesisVersions> versionsList = versionsMapper
                    .selectList(new LambdaQueryWrapper<ThesisVersions>().eq(ThesisVersions::getThesisId, thesisId)
                            .orderByDesc(ThesisVersions::getVersionDate));

            boolean hasApprovedDraft = versionsList.stream().anyMatch(version -> version.getVersionNumber() == 1 &&
                    Objects.equals(version.getStatus(), StatusConstants.TWO)); // 初稿通过

            boolean hasApprovedFinal = versionsList.stream().anyMatch(version -> version.getVersionNumber() == 2 &&
                    Objects.equals(version.getStatus(), StatusConstants.TWO)); // 终稿通过

            if (hasApprovedDraft && hasApprovedFinal) {
                // 初稿和终稿都已通过，抛出异常
                throw new ObjectException("初稿和终稿都已通过，无法继续添加论文！");
            }

            if (!hasApprovedDraft) {
                // 初稿未通过，抛出异常
                throw new ObjectException("初稿未通过，无法提交终稿！");
            }

            // 添加终稿版本信息
            log.info("添加终稿论文，学生ID：{}", studentId);

            ThesisVersions thesisVersions = ThesisVersions.builder().thesisId(thesisId) // 使用已有论文ID
                    .versionNumber(2) // 终稿
                    .versionDate(LocalDateTime.now()).fileUrl(theseDto.getFileUrl()).status(StatusConstants.ZERO) // 状态：待审核
                    .build();
            versionsMapper.insert(thesisVersions);

            log.info("终稿论文添加成功，论文版本ID：{}", thesisVersions.getVersionId());
        }
    }

    /**
     * 修改论文信息
     *
     * @param thesisId 论文ID
     * @param theseDto 修改后的论文信息
     */
    @Transactional
    @Override
    public void update(Integer thesisId, TheseDto theseDto) {
        // 查询论文是否存在
        Theses theses = baseMapper.selectById(thesisId);
        if (theses == null) {
            throw new ObjectException("论文不存在");
        }

        // 查询论文的最新版本信息
        ThesisVersions currentVersion = versionsMapper.selectLatestVersionByThesisId(thesisId);
        if (currentVersion == null) {
            throw new ObjectException("论文版本信息不存在");
        }

        if (Objects.equals(theses.getStatus(), StatusConstants.TWO) && Objects.equals(currentVersion.getStatus(), StatusConstants.TWO)) {
            throw new ObjectException(currentVersion.getVersionNumber() == 1 ? "初稿通过了" : "终稿通过了");
        }

        // 更新论文基本信息
        theses.setTitle(theseDto.getTitle());
        theses.setLastUpdated(LocalDateTime.now());
        baseMapper.updateById(theses);

        // 更新版本信息
        currentVersion.setFileUrl(theseDto.getFileUrl());
        currentVersion.setVersionDate(LocalDateTime.now());
        currentVersion.setStatus(StatusConstants.ZERO); // 状态设置为待审
        versionsMapper.updateById(currentVersion);
    }

    @Transactional
    @Override
    public void deleteThesisAndRelatedInfo(Integer thesisId) {
        // 检查论文是否存在
        Theses theses = baseMapper.selectById(thesisId);
        if (theses == null) {
            throw new ObjectException("论文不存在");
        }

        // 删除论文的评审信息
        int reviewsDeleted = reviewsMapper.delete(new LambdaQueryWrapper<ThesisReviews>().eq(ThesisReviews::getThesisId, thesisId));
        log.info("已删除论文评审信息数量：{}", reviewsDeleted);

        // 删除论文的版本信息
        int versionsDeleted = versionsMapper.delete(new LambdaQueryWrapper<ThesisVersions>().eq(ThesisVersions::getThesisId, thesisId));
        log.info("已删除版本信息数量：{}", versionsDeleted);

        // 删除论文信息
        int thesesDeleted = baseMapper.deleteById(thesisId);
        if (thesesDeleted == 0) {
            throw new ObjectException("论文删除失败");
        }
        log.info("论文删除成功：论文ID={}", thesisId);
    }

    /**
     * 根据学生id 获取学生提交的所有论文
     *
     * @param id 学生id
     * @return 论文列表
     */
    @Override
    public List<ThesesVO> list(Integer id) {
        // 获取该学生的所有论文
        List<Theses> thesesList = baseMapper.selectList(new LambdaQueryWrapper<Theses>().eq(Theses::getStudentId, id));

        if (thesesList.isEmpty()) {
            return Collections.emptyList(); // 如果没有论文，返回空列表
        }

        // 收集所有论文ID，用于批量查询评审和版本信息
        List<Integer> thesisIds = thesesList.stream()
                .map(Theses::getThesisId)
                .collect(Collectors.toList());

        // 批量查询所有论文的评审信息
        List<ThesisReviews> reviewsList = reviewsMapper.selectList(new LambdaQueryWrapper<ThesisReviews>()
                .in(ThesisReviews::getThesisId, thesisIds));

        // 批量查询所有论文的版本信息
        List<ThesisVersions> versionsList = versionsMapper.selectList(new LambdaQueryWrapper<ThesisVersions>()
                .in(ThesisVersions::getThesisId, thesisIds));

        // 将论文、评审、版本信息关联到ThesesVO
        List<ThesesVO> thesesVOList = new ArrayList<>();
        thesesList.forEach(theses -> {
            ThesesVO thesesVO = BeanUtil.copyProperties(theses, ThesesVO.class);

            // 查找当前论文对应的评审和版本信息
            ThesisReviews review = reviewsList.stream()
                    .filter(r -> r.getThesisId().equals(theses.getThesisId()))
                    .findFirst()
                    .orElse(null);

            ThesisVersions version = versionsList.stream()
                    .filter(v -> v.getThesisId().equals(theses.getThesisId()))
                    .findFirst()
                    .orElse(null);

            thesesVO.setReview(review);  // 设置评审信息
            thesesVO.setVersion(version);  // 设置版本信息
            thesesVOList.add(thesesVO);
        });

        return thesesVOList;
    }


    /**
     * 导师评审论文
     *
     * @param theseDto dto
     */
    @Transactional
    @Override
    public void reviewPaper(@NotNull AdvisorUpdateTheseDto theseDto) {
        Integer thesisId = theseDto.getThesisId();
        Integer status = theseDto.getStatus();
        String comments = theseDto.getComments();
        Integer score = theseDto.getScore();
        Integer advisorId = theseDto.getAdvisorId();

        // 校验输入参数
        validateReviewInputs(thesisId, status, comments);

        // 查询是否已存在评审记录
        ThesisReviews existingReview = reviewsMapper.selectOne(
                new LambdaQueryWrapper<ThesisReviews>().eq(ThesisReviews::getAdvisorId, advisorId).eq(ThesisReviews::getThesisId, thesisId));

        // 构建评审表数据
        ThesisReviews thesisReviews = existingReview == null
                ? ThesisReviews.builder()
                .reviewStatus(status)
                .comments(comments)
                .score(score)
                .advisorId(advisorId)
                .thesisId(thesisId)
                .reviewDate(LocalDateTime.now())
                .build()
                : existingReview.setReviewStatus(status).setScore(score).setComments(comments);

        // 如果状态为退回，设置退回原因
        if (status.equals(StatusConstants.ONE) || status.equals(StatusConstants.THREE)) {
            thesisReviews.setReturnReason(comments);
        }

        // 更新论文表状态
        boolean updatedTheses = updateThesisStatus(thesisId, status);

        // 插入或更新评审记录
        boolean updatedReviews = existingReview == null
                ? reviewsMapper.insert(thesisReviews) > 0
                : reviewsMapper.update(thesisReviews, new LambdaUpdateWrapper<ThesisReviews>().eq(ThesisReviews::getThesisId, thesisId)) > 0;
        // 更新版本表状态
        boolean updatedVersions = updateThesisVersion(thesisId, status, comments);

        // 检查更新结果
        if (!updatedTheses || !updatedReviews || !updatedVersions) {
            throw new ObjectException(MessageConstants.UPDATE_FAIL);
        }
    }

    /**
     * 校验输入参数
     */
    private void validateReviewInputs(Integer thesisId, Integer status, String comments) {
        if (thesisId == null || status == null || StringUtils.isBlank(comments)) {
            throw new ObjectException(MessageConstants.NULL);
        }
        if (!isValidStatus(status)) {
            throw new ObjectException(MessageConstants.INVALID_STATUS);
        }
    }

    /**
     * 更新论文表状态
     */
    private boolean updateThesisStatus(Integer thesisId, Integer status) {
        return baseMapper.updateById(
                Theses.builder().status(status).thesisId(thesisId).lastUpdated(LocalDateTime.now()).build()
        ) > 0;
    }

    /**
     * 更新版本表状态
     */
    private boolean updateThesisVersion(Integer thesisId, Integer status, String comments) {
        ThesisVersions thesisVersions = ThesisVersions.builder()
                .status(status)
                .build();
        if (status.equals(StatusConstants.ONE) || status.equals(StatusConstants.THREE)) {
            thesisVersions.setReturnReason(comments);
        }
        return versionsMapper.update(thesisVersions, new LambdaUpdateWrapper<ThesisVersions>().eq(ThesisVersions::getThesisId, thesisId)) > 0;
    }


    /**
     * 检查状态是否合法
     *
     * @param status 状态值
     * @return 是否合法
     */
    private boolean isValidStatus(Integer status) {
        return status.equals(StatusConstants.ONE) || // 待审
                status.equals(StatusConstants.TWO) || // 通过
                status.equals(StatusConstants.THREE); // 拒绝
    }


}
